package Core

import (
	"fmt"
	"time"
	"log"
	"path"
	"os"
	"sync"
)

// declare Logger var
var Logger *HxLogger

// declare HxLogger struct
type HxLogger struct {
	clockTime   int
	dir         string
	logs        []string
	errorLogs   []string
	// use io locker
	sync.RWMutex
}

// Log message
func (this *HxLogger) Log(v...interface {}) {
	str := fmt.Sprintln(v...)
	str = time.Now().Format("2006-01-02 15:04:05") + "\t" + str
	this.logs = append(this.logs, str)
}

// Log error message
func (this *HxLogger) Err(v...interface {}) {
	str := fmt.Sprintln(v...)
	str = time.Now().Format("2006-01-02 15:04:05") + "\t" + str
	this.errorLogs = append(this.errorLogs, str)
}

// write logging messages
func (this *HxLogger) writeLogs() {
	if len(this.logs) > 0 {
		fs, e := os.OpenFile(this.getCurrentFile(), os.O_WRONLY | os.O_APPEND | os.O_CREATE, 0660)
		if e != nil {
			panic(e)
		}
		this.RLock()
		for _, log := range this.logs {
			fs.Write([]byte(log))
		}
		this.logs = []string{}
		defer this.RUnlock()
		defer fs.Close()
	}
}

// write error loggings
func (this *HxLogger) writeErrLogs() {
	if len(this.errorLogs) > 0 {
		fs, e := os.OpenFile(path.Join(this.dir, "error_log.log"), os.O_WRONLY | os.O_APPEND | os.O_CREATE, 0660)
		if e != nil {
			panic(e)
		}
		this.RLock()
		for _, log := range this.errorLogs {
			content := time.Now().Format("2006-01-02 15:04:05") + "\t" + log
			fs.Write([]byte(content))
		}
		this.errorLogs = []string{}
		defer this.RUnlock()
		defer fs.Close()
	}
}

// Write logs
func (this *HxLogger) syncWrite() {
	logsLength := len(this.logs) + len(this.errorLogs)
	this.writeLogs()
	this.writeErrLogs()
	log.Println("logger sync write @", logsLength, "logs")
	// redo after clock time
	time.AfterFunc(time.Duration(this.clockTime)*time.Second, func() {
			this.syncWrite()
		})
}

// get current log file name
func (this *HxLogger) getCurrentFile() string {
	fileName := "access_" + time.Now().Format("2006_01_02")
	fileName += ".log"
	return path.Join(this.dir, fileName)
}

// create new *HxLogger
func newLogger() {
	Logger = &HxLogger{}
	Logger.clockTime = Config.IntOr("logger.clock", 60)
	Logger.dir = Config.String("logger.dir")
	Logger.logs = []string{"begin access logging\n"}
	Logger.errorLogs = []string{"begin error logging\n"}
	Logger.syncWrite()
}


